using UnityEngine;

/// <summary>
/// 阳光生成配置数据
/// </summary>
[CreateAssetMenu(fileName = "SunSpawnConfig", menuName = "创建ScriptableObject/SunSpawnConfig", order = 1)]
public class SunSpawnConfig : ScriptableObject
{
    [Header("生成间隔设置")]
    [Tooltip("最小生成间隔（秒）")]
    public float MinInterval = 5f;

    [Tooltip("最大生成间隔（秒）")]
    public float MaxInterval = 15f;

    [Header("阳光价值设置")]
    [Tooltip("最小阳光价值")]
    public int MinSunValue = 15;

    [Tooltip("最大阳光价值")]
    public int MaxSunValue = 25;

    [Header("生成区域设置")]
    [Tooltip("生成区域宽度")]
    public float SpawnAreaWidth = 20f;

    [Tooltip("生成区域深度")]
    public float SpawnAreaDepth = 10f;

    [Tooltip("生成高度")]
    public float SpawnHeight = 15f;

    [Header("动画设置")]
    [Tooltip("飘落动画持续时间")]
    public float FallDuration = 2f;

    [Header("抛物线动画设置")]
    [Tooltip("抛物线最高点高度（相对于起始高度）")]
    public float ParabolaHeight = 5f;

    [Tooltip("抛物线水平偏移距离")]
    public float ParabolaHorizontalOffset = 3f;

    [Tooltip("是否启用抛物线动画")]
    public bool EnableParabolicAnimation = true;

    [Tooltip("抛物线动画缓动类型（控制飘落速度变化）")]
    [SerializeField] private UnityEngine.AnimationCurve _parabolaEasing;

    [Tooltip("抛物线控制点数量（更多点=更平滑）")]
    [Range(3, 20)]
    public int ParabolaControlPoints = 8;

    [Header("预制体设置")]
    [Tooltip("阳光预制体")]
    public GameObject SunPrefab;

    [Header("高级设置")]
    [Tooltip("是否启用随机旋转")]
    public bool EnableRandomRotation = true;

    [Tooltip("是否启用随机缩放")]
    public bool EnableRandomScale = false;

    [Tooltip("随机缩放范围")]
    public Vector2 ScaleRange = new Vector2(0.8f, 1.2f);

    /// <summary>
    /// 抛物线动画缓动曲线属性
    /// </summary>
    public UnityEngine.AnimationCurve ParabolaEasing
    {
        get
        {
            if (_parabolaEasing == null)
            {
                _parabolaEasing = new UnityEngine.AnimationCurve();
                _parabolaEasing.AddKey(0f, 0f);
                _parabolaEasing.AddKey(1f, 1f);
            }
            else
            {
                // 尝试评估曲线以检查是否有效
                try
                {
                    float test = _parabolaEasing.Evaluate(0f);
                    test = _parabolaEasing.Evaluate(1f);
                    test = _parabolaEasing.Evaluate(0.5f);
                    // 如果评估成功，说明曲线是有效的
                }
                catch
                {
                    // 如果评估失败，重新初始化
                    _parabolaEasing = new UnityEngine.AnimationCurve();
                    _parabolaEasing.AddKey(0f, 0f);
                    _parabolaEasing.AddKey(1f, 1f);
                }
            }
            return _parabolaEasing;
        }
        set { _parabolaEasing = value; }
    }

    /// <summary>
    /// 获取随机生成间隔
    /// </summary>
    public float GetRandomInterval()
    {
        return Random.Range(MinInterval, MaxInterval);
    }

    /// <summary>
    /// 获取随机阳光价值
    /// </summary>
    public int GetRandomSunValue()
    {
        return Random.Range(MinSunValue, MaxSunValue + 1);
    }

    /// <summary>
    /// 获取随机生成位置
    /// </summary>
    public Vector3 GetRandomSpawnPosition(Vector3 basePosition)
    {
        Vector3 randomOffset = new Vector3(
            Random.Range(-SpawnAreaWidth / 2f, SpawnAreaWidth / 2f),
            SpawnHeight,
            Random.Range(-SpawnAreaDepth / 2f, SpawnAreaDepth / 2f)
        );

        return basePosition + randomOffset;
    }

    /// <summary>
    /// 获取随机旋转
    /// </summary>
    public Quaternion GetRandomRotation()
    {
        if (EnableRandomRotation)
        {
            return Quaternion.Euler(0, Random.Range(0f, 360f), 0);
        }
        return Quaternion.identity;
    }

    /// <summary>
    /// 获取随机缩放
    /// </summary>
    public Vector3 GetRandomScale()
    {
        if (EnableRandomScale)
        {
            float scale = Random.Range(ScaleRange.x, ScaleRange.y);
            return Vector3.one * scale;
        }
        return Vector3.one;
    }

    /// <summary>
    /// 验证配置数据
    /// </summary>
    public bool ValidateConfig()
    {
        if (MinInterval <= 0 || MaxInterval <= 0)
        {
            Logger.LogError("生成间隔必须大于0");
            return false;
        }

        if (MinInterval > MaxInterval)
        {
            Logger.LogError("最小间隔不能大于最大间隔");
            return false;
        }

        if (MinSunValue <= 0 || MaxSunValue <= 0)
        {
            Logger.LogError("阳光价值必须大于0");
            return false;
        }

        if (MinSunValue > MaxSunValue)
        {
            Logger.LogError("最小阳光价值不能大于最大阳光价值");
            return false;
        }

        if (SpawnAreaWidth <= 0 || SpawnAreaDepth <= 0)
        {
            Logger.LogError("生成区域尺寸必须大于0");
            return false;
        }

        if (SpawnHeight <= 0)
        {
            Logger.LogError("生成高度必须大于0");
            return false;
        }

        if (FallDuration <= 0)
        {
            Logger.LogError("飘落动画持续时间必须大于0");
            return false;
        }

        return true;
    }

    /// <summary>
    /// 计算抛物线路径点
    /// </summary>
    /// <param name="startPos">起始位置</param>
    /// <param name="endPos">结束位置</param>
    /// <returns>抛物线路径点数组</returns>
    public Vector3[] CalculateParabolicPath(Vector3 startPos, Vector3 endPos)
    {
        if (!EnableParabolicAnimation)
        {
            return new Vector3[] { startPos, endPos };
        }

        Vector3[] pathPoints = new Vector3[ParabolaControlPoints];

        // 计算抛物线顶点
        Vector3 midPoint = Vector3.Lerp(startPos, endPos, 0.5f);
        Vector3 peakPoint = midPoint + Vector3.up * ParabolaHeight;

        // 添加水平偏移
        Vector3 direction = (endPos - startPos).normalized;
        Vector3 rightDirection = Vector3.Cross(direction, Vector3.up);
        peakPoint += rightDirection * ParabolaHorizontalOffset;

        // 使用Catmull-Rom样条曲线生成平滑路径
        for (int i = 0; i < ParabolaControlPoints; i++)
        {
            float t = (float)i / (ParabolaControlPoints - 1);
            pathPoints[i] = CalculateCatmullRomPoint(startPos, peakPoint, endPos, t);
        }

        return pathPoints;
    }

    /// <summary>
    /// 计算Catmull-Rom样条曲线上的点
    /// </summary>
    private Vector3 CalculateCatmullRomPoint(Vector3 p0, Vector3 p1, Vector3 p2, float t)
    {
        // 简化的Catmull-Rom样条曲线计算
        // 使用二次贝塞尔曲线近似
        Vector3 p01 = Vector3.Lerp(p0, p1, t);
        Vector3 p12 = Vector3.Lerp(p1, p2, t);
        return Vector3.Lerp(p01, p12, t);
    }

    /// <summary>
    /// 获取抛物线动画的DOTween路径
    /// </summary>
    public Vector3[] GetParabolicDOTweenPath(Vector3 startPos, Vector3 endPos)
    {
        if (!EnableParabolicAnimation)
        {
            return new Vector3[] { startPos, endPos };
        }

        Vector3[] pathPoints = CalculateParabolicPath(startPos, endPos);

        // 为DOTween创建路径数组
        Vector3[] dotweenPath = new Vector3[pathPoints.Length];
        for (int i = 0; i < pathPoints.Length; i++)
        {
            dotweenPath[i] = pathPoints[i];
        }

        return dotweenPath;
    }

    /// <summary>
    /// 初始化抛物线缓动曲线
    /// </summary>
    private void InitializeParabolaEasing()
    {
        if (_parabolaEasing == null)
        {
            _parabolaEasing = new UnityEngine.AnimationCurve();
            _parabolaEasing.AddKey(0f, 0f);
            _parabolaEasing.AddKey(1f, 1f);
        }
        else
        {
            // 尝试评估曲线以检查是否有效
            try
            {
                float test = _parabolaEasing.Evaluate(0f);
                test = _parabolaEasing.Evaluate(1f);
                test = _parabolaEasing.Evaluate(0.5f);
                // 如果评估成功，说明曲线是有效的
            }
            catch
            {
                // 如果评估失败，重新初始化
                _parabolaEasing = new UnityEngine.AnimationCurve();
                _parabolaEasing.AddKey(0f, 0f);
                _parabolaEasing.AddKey(1f, 1f);
            }
        }
    }

    /// <summary>
    /// 获取抛物线缓动值
    /// </summary>
    public float GetParabolaEasingValue(float t)
    {
        // 确保输入值在有效范围内
        t = Mathf.Clamp01(t);
        
        InitializeParabolaEasing();
        
        if (ParabolaEasing == null)
        {
            Logger.LogWarning("ParabolaEasing is null, returning default value");
            return t; // 返回原始值作为备用
        }
        
        try
        {
            float value = ParabolaEasing.Evaluate(t);
            
            // 检查返回的值是否有效
            if (float.IsNaN(value) || float.IsInfinity(value))
            {
                Logger.LogWarning($"ParabolaEasing.Evaluate({t}) 返回无效值: {value}, 使用原始值");
                return t;
            }
            
            return Mathf.Clamp01(value);
        }
        catch (System.Exception e)
        {
            Logger.LogWarning($"ParabolaEasing.Evaluate 失败: {e.Message}, 使用原始值");
            return t;
        }
    }

    /// <summary>
    /// 在Inspector中验证属性
    /// </summary>
    private void OnValidate()
    {
        // 确保抛物线缓动曲线有效
        InitializeParabolaEasing();

        // 验证其他参数的合理性
        if (MinInterval > MaxInterval)
        {
            MinInterval = MaxInterval;
        }

        if (MinSunValue > MaxSunValue)
        {
            MinSunValue = MaxSunValue;
        }
    }

    /// <summary>
    /// 在资源被启用时初始化
    /// </summary>
    private void OnEnable()
    {
        // 确保AnimationCurve被初始化
        InitializeParabolaEasing();
    }

    /// <summary>
    /// 重置为默认值
    /// </summary>
    [ContextMenu("重置为默认值")]
    public void ResetToDefaults()
    {
        MinInterval = 5f;
        MaxInterval = 15f;
        MinSunValue = 15;
        MaxSunValue = 25;
        SpawnAreaWidth = 20f;
        SpawnAreaDepth = 10f;
        SpawnHeight = 15f;
        FallDuration = 2f;
        EnableRandomRotation = true;
        EnableRandomScale = false;
        ScaleRange = new Vector2(0.8f, 1.2f);

        // 抛物线动画默认值（更明显的曲线效果）
        ParabolaHeight = 8f;
        ParabolaHorizontalOffset = 5f;
        EnableParabolicAnimation = true;
        ParabolaControlPoints = 12;

        // 初始化抛物线缓动曲线
        _parabolaEasing = new UnityEngine.AnimationCurve();
        _parabolaEasing.AddKey(0f, 0f);
        _parabolaEasing.AddKey(1f, 1f);
    }

    /// <summary>
    /// 确保在Awake时也初始化
    /// </summary>
    private void Awake()
    {
        InitializeParabolaEasing();
    }
}